package com.whosly.mysql.protocol.code;

import lombok.Getter;
import org.apache.commons.lang3.StringUtils;

/**
 * @author fengyang
 * @date 2023/8/17 下午8:57
 * @see <a href="yueny09@163.com">mailTo: yueny09@163.com</a>
 */
public class MysqlProtocolException extends RuntimeException {
    /**
     * 错误信息分隔符
     */
    private static final String MESSAGE_SPLIT = ":";

    @Getter
    private final IErrorCodeType code;

    /**
     * 错误信息
     */
    @Getter
    private final String errorMsg;

    public MysqlProtocolException(IErrorCodeType errorCode) {
        this(errorCode, "");
    }

    public MysqlProtocolException(String message) {
        this(ErrorCodeType.MYSQL_PROTOCOL_ERROR, message);
    }

    public MysqlProtocolException(IErrorCodeType errorCode, String message) {
        super(message);
        this.code = errorCode;
        this.errorMsg = message;
    }

    public MysqlProtocolException(IErrorCodeType errorCode, Throwable cause) {
        this(errorCode, "", cause);
    }

    public MysqlProtocolException(IErrorCodeType errorCode, Throwable cause, boolean containsErrorMsg) {
        this(errorCode, "", cause, containsErrorMsg);
    }

    public MysqlProtocolException(IErrorCodeType errorCode, String message, Throwable cause) {
        this(errorCode, message, cause, false);
    }

    public MysqlProtocolException(IErrorCodeType errorCode, String message, Throwable cause, boolean containsErrorMsg) {
        super(message, cause);
        this.code = errorCode;

        // 取code对应的 msg
        String msg = containsErrorMsg
                ? appendErrorMessage(message, cause.getMessage()) : message;
        this.errorMsg = msg;
    }

    private String appendErrorMessage(String... messages) {
        StringBuilder sb = new StringBuilder();
        if (messages == null || messages.length == 0) {
            return sb.toString();
        }
        for (String message : messages) {
            if (StringUtils.isNotEmpty(message)) {
                sb.append(message).append(MESSAGE_SPLIT);
            }
        }
        if (sb.length() > 0) {
            // 删除最后一个分隔符，使用删除的方式处理数组中以空字符串结尾的情况
            sb.delete(sb.length() - 1, sb.length());
        }
        return sb.toString();
    }

    /**
     * 重写。 getMessage和getErrorMsg 返回加工过的错误信息
     */
    @Override
    public String getMessage() {
        return getErrorMsg();
    }

    public static MysqlProtocolException of(IErrorCodeType errorCode, String message) {
        return new MysqlProtocolException(errorCode, message);
    }

    public static MysqlProtocolException of(IErrorCodeType errorCode, String message, Throwable cause) {
        return new MysqlProtocolException(errorCode, message, cause);
    }
}
